"""
用户控制用户一定的时间内访问的次数
"""
from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
import time


"""
自定义写法
"""
# 记录用户的访问时间，可以存放到数据库，如果定义字典形式存储，放入缓存中
VISIT_LIMIT = {}
class VisitThrottle(object):

    def __init__(self):
        self.history = None


    """60s内只能访问3次"""
    def allow_request(self,request,view):
        """
        最简单的使用
        :param request:
        :param view:
        :return:
        """
        # return True         # 如果是True表示还可以继续访问，没有到达访问频率的要求
        # # return False          # return False表示访问频率太高，被限制

        # 1、获取用户的IP，基于IP控制访问频率，也可以改成用户名的方式，这里获取用户即可
        remote_addr = request.META.get('REMOTE_ADDR')
        ctime = time.time()
        # 当IP不存在这个字典中，则加入字典；也可以保存到数据库中；key：访问的IP   value：访问的时间
        if remote_addr not in VISIT_LIMIT:
            VISIT_LIMIT[remote_addr] = [ctime,]
            return True
        # 如果存在则从字典中获取访问的记录，并进行判断
        history = VISIT_LIMIT.get(remote_addr)
        # 把用户的记录赋值
        self.history = history
        # 循环用户的访问记录并且获取最后一个值进行判断，是否小于 当前时间 - 10
        # - 10 代表10秒内访问的次数
        while history and history[-1] < ctime - 10:
            """
            这段循环的意思：
            [10:13:50，10:13:40，10:13:30，10:13:20]；获取出来的时间 离现在最远的时间放在最后的
            一直while循环读取这个列表最后一个值，如果时间小于 当前时间 - 10
            则删除这个列表最后一个值
            直到列表最后一个值 大于 当前时间 - 10
            """
            # 删除末尾的值
            history.pop()

        # 控制一定时间内 访问的次数
        if len(history) < 3:
            """
            经过判断时间，删除了一个个数的元素，统计剩下列表元素个数是否小于3
            """
            # 如果元素小于则可以访问，插入一次的访问记录
            history.insert(0,ctime)
            return True

    def wait(self):
        """
        还需要等待多少秒才能访问

        :return:
        """
        # 提示多少能访问
        # 获取当前时间
        ctime = time.time()
        # 10s   - （ 当前时间 - 用户访问的最近一次时间 ）  = 还有几秒可以访问
        return 10 - (ctime - self.history[-1])




# 继承类的写法
VISIT_LIMIT = {}
class VisitThrottles(BaseThrottle):

    def __init__(self):
        self.history = None


    """60s内只能访问3次"""
    def allow_request(self,request,view):
        """
        最简单的使用
        :param request:
        :param view:
        :return:
        """
        # return True         # 如果是True表示还可以继续访问，没有到达访问频率的要求
        # # return False          # return False表示访问频率太高，被限制

        # 1、获取用户的唯一标识
        remote_addr = self.get_ident(request)
        ctime = time.time()
        # 当IP不存在这个字典中，则加入字典；也可以保存到数据库中；key：访问的IP   value：访问的时间
        if remote_addr not in VISIT_LIMIT:
            VISIT_LIMIT[remote_addr] = [ctime,]
            return True
        # 如果存在则从字典中获取访问的记录，并进行判断
        history = VISIT_LIMIT.get(remote_addr)
        # 把用户的记录赋值
        self.history = history
        # 循环用户的访问记录并且获取最后一个值进行判断，是否小于 当前时间 - 10
        # - 10 代表10秒内访问的次数
        while history and history[-1] < ctime - 10:
            """
            这段循环的意思：
            [10:13:50，10:13:40，10:13:30，10:13:20]；获取出来的时间 离现在最远的时间放在最后的
            一直while循环读取这个列表最后一个值，如果时间小于 当前时间 - 10
            则删除这个列表最后一个值
            直到列表最后一个值 大于 当前时间 - 10
            """
            # 删除末尾的值
            history.pop()

        # 控制一定时间内 访问的次数
        if len(history) < 3:
            """
            经过判断时间，删除了一个个数的元素，统计剩下列表元素个数是否小于3
            """
            # 如果元素小于则可以访问，插入一次的访问记录
            history.insert(0,ctime)
            return True

    def wait(self):
        """
        还需要等待多少秒才能访问

        :return:
        """
        # 提示多少能访问
        # 获取当前时间
        ctime = time.time()
        # 10s   - （ 当前时间 - 用户访问的最近一次时间 ）  = 还有几秒可以访问
        return 10 - (ctime - self.history[-1])


"""
django自带的写法  不用以上自己写了
"""
# 针对匿名用户操作
class VisitThrottle(SimpleRateThrottle):
    # 自定义一个值
    scope = 'Luffy'

    def get_cache_key(self, request, view):
        return self.get_ident(request)
"""
setting文件中的配置：
REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_RATES': {'Luffy':'3/m'},                                   # 基于django自己写的，代表1分钟内访问3次
}
"""



# 针对登录用户操作
class UserThrottle(SimpleRateThrottle):
    # 自定义一个值
    scope = 'LuffyUser'

    def get_cache_key(self, request, view):
        return request.user.username
"""
setting文件中的配置：
REST_FRAMEWORK = {

    'DEFAULT_THROTTLE_RATES': {'LuffyUser':'10/m'},                                   # 基于django自己写的，代表1分钟内访问3次
}
"""